#pragma once

#include "../EntityManager.h"
#include "../Utility.h"
#include "../Market/Comodities.h"

#include "Platform.h"

class OutputManager
{
private:
	// An instance of Storage Data.
	// Every instance that correpsonds to the same entity must be adjacent in memory.
	struct InstanceData
	{
		uint32 size;
		uint32 capacity;
		void* buffer;

		// Data.
		Entity* entity;				// The entity owning this instance.
		float* storage;
		float* max_storage;
		float* rate;				// The maximum amount consumed or produced per production cycle.
		float* ratio;				// The ratio of the rate to the available invintory. Note that by definition this can't be higher than one.
		uint32* comodity_index;
		uint32* max_range;
		uint32* min_range;
	};

private:
	InstanceData _data;
	uint32 entity_count;

	void Allocate(const uint32 capacity);
	void SortData(const uint32 start, const uint32 stop);

public:
	OutputManager();
	~OutputManager();

	void CalculateOutputRatio();
	void InitializeProduction(Entity* entities, float* production);
	void OverrideRatios(const uint32 entity_count, Entity* entities, float* production);
	void ProduceOutput();

	void PlaceMarketSells(BidData* bids) const;
	void RegisterSellResults(const BidData* const bids, const float* const comodity_mean, const float* const comodity_supply, const float* const comodity_demand, const uint32 num_resources);
	void RemoveOutputData(const OpenVector<Entity>& defunct_entities, OpenVector<uint32>& defunct_sellers);
	void AllocateStorage(const Entity* const entities, const uint32 num_entities, const uint32 input_cost, const uint32* const comodity_indexes, const float* const comodity_rates, const uint32 num_outputs,
		const float* const mean_prices);

	inline const uint32 GetEntityCount() { return entity_count; }
};